from __future__ import division

import sys, os.path, argparse, logging, itertools, time, glob

import numpy, scipy.optimize, scipy.stats
from numpy import array

import common, wlc, kinetics_opt, stats

exec("from numpy import %s" % kinetics_opt.bestfloat.__name__)

if not hasattr(numpy, "float96"):
    numpy.float96 = kinetics_opt.bestfloat
    from numpy import float96
if not hasattr(numpy, "float128"):
    numpy.float128 = kinetics_opt.bestfloat
    from numpy import float128

logger = logging.getLogger("kinetics_opt_bootstrapping")
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.INFO)

def main(params):
    parser = argparse.ArgumentParser()
    parser.add_argument("--results_repr_glob")

    args = parser.parse_args(params)
    logger.info("%s", args)

    curve_stretch_playlist2diffuse_dxs = {}
    for results_repr_path in glob.glob(args.results_repr_glob):
        logger.info(results_repr_path)
        with open(results_repr_path, "rb") as in_file:
            for line in in_file:
                # Normally, there should be only one file, but perpahs one wants to
                # concatenate multiple results files.
                r = eval(line)
                (curve_stretch_playlists, seeds, peak_indices_list_list,
                 standard_method_dx_k0_list, mle_list, shared_dx_mle_row) = r
                for curve_stretch_playlist, mle in zip(
                    curve_stretch_playlists, mle_list):
                    (fixed_dx_k0_lls_list, dx, k0, lls,
                     diffuse_fixed_dx_k0, diffuse_fixed_dx_k0_lls_list,
                     diffuse_dx, diffuse_k0, diffuse_lls) = mle
                    v = curve_stretch_playlist2diffuse_dxs.setdefault(
                        curve_stretch_playlist, [])
                    v.append(diffuse_dx)
    curve_stretch_playlist_diffuse_dxs_list = sorted(
        curve_stretch_playlist2diffuse_dxs.items())
    curve_stretch_playlists, diffuse_dxs_list = zip(
        *curve_stretch_playlist_diffuse_dxs_list)
    diffuse_dxs_list = [
        curve_stretch_playlist2diffuse_dxs[curve_stretch_playlist]
        for curve_stretch_playlist in curve_stretch_playlists]
    g = scipy.stats.norm(loc=0, sigma=1)
    p = g.cdf(1) - g.cdf(-1)  # 0.68268949213708585
    dx_stats_list = []
    for diffuse_dxs in diffuse_dxs_list:
        n = len(diffuse_dxs)
        a = sorted(diffuse_dxs)
        m = int(numpy.around(p * n))
        i = numpy.argmin(
            [a[i + m - 1] - a[i] for i in range(n - m + 1)])
        s, e = a[i], a[i + m - 1]
        dx_stats_list.append(
            (numpy.mean(diffuse_dxs), numpy.std(diffuse_dxs, ddof=1), s, e,
             len(diffuse_dxs)))
    for curve_stretch_playlist, dx_stats in zip(
        curve_stretch_playlists, dx_stats_list):
        logger.info(
            "Stats(%s): Average(nm)=%r Stddev(nm)=%r HighestDensityRange[%r](nm)=(%r, %r) Count=%d" % (
                curve_stretch_playlist, dx_stats[0] * 1e9, dx_stats[1] * 1e9, p,
                dx_stats[2] * 1e9, dx_stats[3] * 1e9, dx_stats[4]))

if __name__ == "__main__":
    main(sys.argv[1:])
